package ua.kharkov.khpi.tarasenko.bach.web;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.log4j.Logger;

import ua.kharkov.khpi.tarasenko.bach.core.Constant;
import ua.kharkov.khpi.tarasenko.bach.core.EShopException;
import ua.kharkov.khpi.tarasenko.bach.web.command.Command;
import ua.kharkov.khpi.tarasenko.bach.web.command.CommandManager;

/**
 * Main servlet-controller.
 * 
 * @author oleksandr
 * 
 */
public class MainController extends HttpServlet {

	private static final long serialVersionUID = 5594894986812902722L;
	private static final Logger log = Logger.getLogger(MainController.class);

	@Override
	protected void service(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		String commandName = request.getParameter(Constant.ATTRIBUTE_COMMAND);
		if (log.isTraceEnabled()) {
			log.trace("Got command name \"" + commandName + "\"");
		}
		Command command = CommandManager.getCommand(commandName);
		if (log.isTraceEnabled()) {
			log.trace("Got command \"" + command + "\"");
		}
		String forward = null;
		try {
			forward = command.execute(request, response);
		} catch (EShopException e) {
			String errorMessage = "Internal server error!";
			request.setAttribute(Constant.ATTRIBUTE_ERROR_MESSAGE, errorMessage);
			if (log.isTraceEnabled()) {
				log.trace("Set request attribute "
						+ Constant.ATTRIBUTE_ERROR_MESSAGE + "=" + errorMessage);
			}
			forward = Constant.COMMAND_ERROR_PROCESSING;

			// We should log root exception, so we extract it
			Throwable thr = null;
			if (ExceptionUtils.getRootCause(e) != null) {
				thr = ExceptionUtils.getRootCause(e);
			} else {

				// Exception doesn't have nested exception.
				thr = e;
			}
			log.error(e.getMessage(), thr);
		}

		if (forward != null) {
			RequestDispatcher dispatcher = request
					.getRequestDispatcher(forward);
			dispatcher.forward(request, response);
		} else {

			// Forward should not be null in any way!
			log.warn("Forward is null!");
		}
	}
}
